package cn.framework.dao.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.hibernate.SessionFactory;
import org.hibernate.persister.entity.AbstractEntityPersister;
import org.hibernate.persister.entity.SingleTableEntityPersister;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Service;

@Service
public class DaoUtil extends HibernateDaoSupport {

	@Autowired
	public DaoUtil(@Qualifier("local-hibernateTemplate")
	HibernateTemplate hibernateTemplate) {
		super.setHibernateTemplate(hibernateTemplate);
	}

	/**
	 * 取得数据库中的所有表名
	 * 
	 * @return
	 */
	public List<String> getAllDbTableName() {
		List<String> resultList = new ArrayList<String>();
		SessionFactory factory = getHibernateTemplate().getSessionFactory();
		Map metaMap = factory.getAllClassMetadata();
		for (String key : (Set<String>) metaMap.keySet()) {
			AbstractEntityPersister classMetadata = (SingleTableEntityPersister) metaMap
					.get(key);
			resultList.add(classMetadata.getTableName());
		}
		return resultList;
	}

	/**
	 * 按对象取得相应的表名
	 * 
	 * @param objClass
	 * @return
	 */
	public String getDbTableName(Class objClass) {
		SessionFactory factory = getHibernateTemplate().getSessionFactory();
		Class cls = objClass;
		AbstractEntityPersister classMetadata = (SingleTableEntityPersister) factory
				.getClassMetadata(cls);
		return classMetadata.getTableName();
	}

	/**
	 * 取得对象中所有映射的列名
	 * 
	 * @param objClass
	 * @return
	 */
	public List<String> getDbCellName(Class objClass) {
		List<String> resultList = new ArrayList<String>();
		SessionFactory factory = getHibernateTemplate().getSessionFactory();
		Class cls = objClass;
		AbstractEntityPersister classMetadata = (SingleTableEntityPersister) factory
				.getClassMetadata(cls);
		// 添加主键
		resultList.addAll(Arrays.asList(classMetadata
				.getIdentifierColumnNames()));
		String[] propertyNames = classMetadata.getPropertyNames();
		for (String propertyName : propertyNames) {
			// 判断是否一对多的对像,移除
			boolean isCollection = classMetadata.getClassMetadata()
					.getPropertyType(propertyName).isCollectionType();
			if (!isCollection) {
				String[] propertyColumnNames = classMetadata
						.getPropertyColumnNames(propertyName);
				for (String columnName : propertyColumnNames) {
					resultList.add(columnName);
				}
			}
		}
		return resultList;
	}

	/**
	 * 按列名与对像取出映射对象的字段
	 * 
	 * @param objClass
	 * @param columnName
	 * @return
	 */
	public String getPropertyByColunm(Class objClass, String columnName) {
		SessionFactory factory = getHibernateTemplate().getSessionFactory();
		AbstractEntityPersister classMetadata = (SingleTableEntityPersister) factory
				.getClassMetadata(objClass);
		String[] propertyNames = classMetadata.getPropertyNames();
		for (String propertyName : propertyNames) {
			// 判断是否一对多的对像,移除
			boolean isCollection = classMetadata.getClassMetadata()
					.getPropertyType(propertyName).isCollectionType();
			if (!isCollection) {
				String[] propertyColumnNames = classMetadata
						.getPropertyColumnNames(propertyName);
				for (String tempColumnName : propertyColumnNames) {
					if (columnName.equals(tempColumnName)) {
						return propertyName;
					}
				}
			}
		}
		return null;
	}

	/**
	 * 按列名与对像取出映射对像的类型(不包括主键)
	 * 
	 * @param objClass
	 * @param columnName
	 * @return
	 */
	public Class getPropertyTypeByColumn(Class objClass, String columnName) {
		String propertyName = getPropertyByColunm(objClass, columnName);
		SessionFactory factory = getHibernateTemplate().getSessionFactory();
		AbstractEntityPersister classMetadata = (SingleTableEntityPersister) factory
				.getClassMetadata(objClass);
		return classMetadata.getPropertyType(propertyName).getReturnedClass();
	}
	
	/**
	 * 取得主键propertyColumn
	 * @param objClass
	 * @param columnName
	 * @return
	 */
	public String getPrimaryKeyColumn(Class objClass) {
		List<String> resultList = new ArrayList<String>();
		SessionFactory factory = getHibernateTemplate().getSessionFactory();
		Class cls = objClass;
		AbstractEntityPersister classMetadata = (SingleTableEntityPersister) factory
				.getClassMetadata(cls);
		// 添加主键
		resultList.addAll(Arrays.asList(classMetadata
				.getIdentifierColumnNames()));
		if(!resultList.isEmpty()){
			String propertyName=resultList.get(0);
			return propertyName;
		}
		return null;
	}
	
	/**
	 * 取得主键property
	 * @param objClass
	 * @param columnName
	 * @return
	 */
	public String getPrimaryKeyProperty(Class objClass) {
		List<String> resultList = new ArrayList<String>();
		SessionFactory factory = getHibernateTemplate().getSessionFactory();
		Class cls = objClass;
		AbstractEntityPersister classMetadata = (SingleTableEntityPersister) factory
				.getClassMetadata(cls);
		return classMetadata	.getIdentifierPropertyName();
	}
	
	/**
	 * 取得主键property
	 * @param objClass
	 * @param columnName
	 * @return
	 */
	public Class getPrimaryKeyType(Class objClass) {
		String pk=getPrimaryKeyProperty(objClass);
		String pkMethod="get"+StringUtils.capitalize(pk);
		Method[] methods=objClass.getMethods();           
        for (Method method:methods) {
        	if(method.getName().equals(pkMethod)){   		
        		return method.getReturnType();
        	}
        }
        /*
		Field[] objecFields=objClass.getFields();
		for (Field field : objecFields) {
			if(field.getName().equals(pk)){
				return field.getType();
			}
		}
		*/
		return Long.class;
	}
	
	/**
	 * 取得主键Value
	 * @param Object
	 * @param columnName
	 * @return
	 */
	public Object getPrimaryKeyValue(Object object) {
		String propertyPrimaryKey=getPrimaryKeyProperty(object.getClass());
		String getterMethodName=propertyToGetterMethod(propertyPrimaryKey);

		try {
			Method getterMethod=object.getClass().getMethod(getterMethodName);
			return getterMethod.invoke(object, null);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return null;
	}


	/**
	 * 按列名与对像取出映射对像的setter方法
	 * 
	 * @param objClass
	 * @param columnName
	 * @return
	 */
	public String getSetterMethodByColumn(Class objClass, String columnName) {
		String property = getPropertyByColunm(objClass, columnName);
		return propertyToSetterMethod(property);
	}

	public String getGetterMethodByColumn(Class objClass, String columnName) {
		String property = getPropertyByColunm(objClass, columnName);
		return propertyToGetterMethod(property);
	}

	/**
	 * 把字段转换为setter方法
	 * 
	 * @param property
	 * @return
	 */
	public String propertyToSetterMethod(String property) {
		if (property != null) {
			property = StringUtils.capitalize(property);
			String result = "set" + property;
			return result;
		}
		return null;
	}

	public String propertyToGetterMethod(String property) {
		if (property != null) {
			property = StringUtils.capitalize(property);
			String result = "get" + property;
			return result;
		}
		return null;
	}

	/**
	 * 是否有指定的数据表
	 * 
	 * @param tableName
	 * @return
	 */
	public boolean isExistTableName(String tableName) {
		List<String> allTableNameList = getAllDbTableName();
		for (String tempTableName : allTableNameList) {
			if (tableName.equals(tempTableName)) {
				return true;
			}
		}
		return false;
	}

}
